﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SGS.Cards;
using SGS.Characters;

namespace SGS.Standard
{
    public class PlayerGameInfo
    {
        #region Construct
        public PlayerGameInfo()
        {
        }

        public PlayerGameInfo(Player player, int number, Character selectedCharacter)
        {
            Number = number;

            SelectedCharacter = selectedCharacter;

            CurrentHP = MaxHP = selectedCharacter.MaxBlood;

            JudgeArea = new Stack<SGS.Standard.Actor.HumanAnswerActor.UseCardActor>();
            OwnCards = new CardCollection();
            Live = true;

            OwnerPlayer = player;
        }
        #endregion

        public Player OwnerPlayer
        {
            get;
            protected set;
        }

        #region 游戏局势
        public int Number
        {
            get;
            protected set;
        }

        public bool Live
        {
            get;
            set;
        }
        #endregion

        #region 角色 & 技能
        public Character SelectedCharacter
        {
            get;
            protected set;
        }

        #endregion

        #region 血条 & 手牌
        public virtual int MaxHP
        {
            get;
            set;
        }

        public virtual int CurrentHP
        {
            get;
            set;
        }

        public virtual int MaxCard
        {
            get
            {
                return CurrentHP;
            }
        }

        public virtual CardCollection OwnCards
        {
            get;
            protected set;
        }
        #endregion

        #region 判定区
        public Stack<SGS.Standard.Actor.HumanAnswerActor.UseCardActor> JudgeArea
        {
            get;
            protected set;
        }
        #endregion

        #region 装备区
        private Card _DefenseHorse = null;
        public Card DefenseHorse
        {
            get
            {
                return _DefenseHorse;
            }
            set
            {
                /*if (_DefenseHorse != null)
                {
                    GamePool.Current.RaiseNoticeMessageEvent( GamePool.Current, "{0}装备了{1}", player.PlayerName, card );
                }*/

                _DefenseHorse = value;

                /*if (_DefenseHorse != null)
                {
                    RaiseNoticeMessageEvent( GamePool.Current, "{0}装备了{1}", player.PlayerName, card );
                }*/
            }
        }

        private Card _AttackHorse = null;
        public Card AttackHorse
        {
            get
            {
                return _AttackHorse;
            }
            set
            {
                _AttackHorse = value;
            }
        }

        private Card _Weapon = null;
        public Card Weapon
        {
            get
            {
                return _Weapon;
            }
            set
            {
                _Weapon = value;
            }
        }

        private Card _Armor = null;
        public Card Armor
        {
            get
            {
                return _Armor;
            }
            set
            {
                _Armor = value;
            }
        }
        #endregion

        #region 距离计算
        private int _DistanceToOtherOffset = 0;
        /// <summary>
        /// 进攻距离偏移，默认为0
        /// </summary>
        public int DistanceToOtherOffset
        {
            get
            {
                return _DistanceToOtherOffset;
            }
            internal set
            {
                _DistanceToOtherOffset = value;
            }
        }

        private int _DistanceFromOtherOffset = 0;
        /// <summary>
        /// 防御距离偏移，默认为0
        /// </summary>
        public int DistanceFromOtherOffset
        {
            get
            {
                return _DistanceFromOtherOffset;
            }
            internal set
            {
                _DistanceFromOtherOffset = value;
            }
        }

        /// <summary>
        /// 实际可攻击距离
        /// </summary>
        public int AttackRange
        {
            get
            {
                return AttackRangeOffset + DistanceToOtherOffset;
            }
        }

        // private int _AttackRangeOffset = 1;

        /// <summary>
        /// 攻击距离偏移，默认为1
        /// </summary>
        public int AttackRangeOffset
        {
            get
            {
                if (Weapon == null)
                {
                    return 1; //_AttackRangeOffset;
                }
                else
                {
                    return ((SGS.Cards.Equipment.WeaponCard)Weapon).AttachRangeOffset;
                }
            }
            /*set
            {
                _AttackRangeOffset = value;
            }*/
        }
        #endregion

        #region Helper

        /// <summary>
        /// 检测在目标位置是否包含所有的卡
        /// </summary>
        /// <param name="cards"></param>
        /// <param name="owner"></param>
        /// <param name="equip"></param>
        /// <returns></returns>
        public bool HasCard(IEnumerable<Card> cards, bool owner = true, bool equip = false)
        {
            foreach (Card c in cards)
            {
                if (c == null)
                {
                    continue;
                }

                if ((owner && OwnCards.Has(c))
                    || (equip && (AttackHorse == c || DefenseHorse == c || Armor == c || Weapon == c)))
                {
                    // do nothing
                }
                else
                {
                    return false;
                }
            }

            return true;
        }

        public bool TryRemoveCard(Card card, bool owner = true, bool equip = false)
        {
            return TryRemoveCard(card.AsList(), owner, equip);
        }

        /// <summary>
        /// 移除手牌或装备牌，会触发事件
        /// </summary>
        /// <param name="cards">要移除的牌</param>
        /// <param name="owner">从手牌处移除</param>
        /// <param name="equip">从装备牌处移除</param>
        /// <returns></returns>
        public bool TryRemoveCard(IEnumerable<Card> cards, bool owner = true, bool equip = false)
        {
            if (!HasCard(cards))
            {
                return false;
            }

            foreach (var card in cards)
            {
                if (equip)
                {
                    if (AttackHorse == card)
                    {
                        SGS.Standard.GameLogic.Basic.GL_UnEquip(OwnerPlayer, false, CardType.AttackHorse);
                        continue;
                    }
                    else if (DefenseHorse == card)
                    {
                        SGS.Standard.GameLogic.Basic.GL_UnEquip(OwnerPlayer, false, CardType.DefenseHorse);
                        continue;
                    }
                    else if (Armor == card)
                    {
                        SGS.Standard.GameLogic.Basic.GL_UnEquip(OwnerPlayer, false, CardType.Armor);
                        continue;
                    }
                    else if (Weapon == card)
                    {
                        SGS.Standard.GameLogic.Basic.GL_UnEquip(OwnerPlayer, false, CardType.Weapon);
                        continue;
                    }
                }

                if (owner)
                {
                    if (this.OwnCards.Has(card))
                    {
                        OwnCards.RemoveCard(card.AsList());
                        continue;
                    }
                }

                return false;

            }
            return true;
        }

        /// <summary>
        /// 移除所有手牌和装备，不会触发事件
        /// </summary>
        /// <returns></returns>
        public List<Card> RemoveAllCardWithoutEvent()
        {
            List<Card> cards = new List<Card>();
            cards.AddRange(OwnCards);

            cards.Add(AttackHorse);
            cards.Add(Weapon);
            cards.Add(DefenseHorse);
            cards.Add(Armor);

            AttackHorse = Weapon = DefenseHorse = Armor = null;

            return cards.Where(p => p != null).ToList();
        }

        public List<Card> RemoveJudgeCard()
        {
            List<Card> r = new List<Card>();
            foreach (var j in JudgeArea)
            {
                r.AddRange(j.UsedCards);
            }
            JudgeArea.Clear();

            return r;
        }
        #endregion
    }
}
